承上文 在 C# 中 Nullable Reference Types 使用屬性AllowNull
繼續探討...
假設我們有一個方法檢查變數是否為 null。根據此檢查的結果,該方法返回 bool 類型的值。
示例:
bool CheckNotNull(object? obj)
{
return obj != null;
}
使用此方法:
public void Foo(object? obj1)
{
object obj2 = new object();
if (CheckNotNull(obj1))
obj2 = obj1;
}
編譯器將對上面的程式碼發出警告:
警告訊息如下:
警告 CS8600 正在將 Null 常值或可能的 Null 值轉換為不可為 Null 的型別。
但這段程式碼NULL情況是不可能發生的,因為已經先檢查確保不為空。問題是編譯器無法理解這個情況,所以我們必須幫助它。
我們可以加入屬性 NotNullWhen 來更改 CheckNotNull() 的簽名:
bool CheckNotNull([NotNullWhen(true)]object? obj)
此屬性將將參數的 Null 狀態與 檢查方法的回傳值 相關聯。
用來向編譯器“解釋”,如果方法返回 true,則該參數 obj 具有值非空。
這個NotNullWhen 屬性還有一些特性如下:
若使用out修飾符
bool GetValidOrDefaultName([NotNullWhen(true)] out string? validOrDefaultName,
string name)
{
if (name == null)
{
validOrDefaultName = name;
return true;
}
else
{
validOrDefaultName = "defaultName";
return false;
}
}
編譯器將對上面的程式碼發出警告:
警告訊息如下:
警告 CS8762 參數 'validOrDefaultName' 在以 'true' 結束時必須具有非 Null 值。
這裡警告非常合理,因為你用了NotNullWhen屬性向編譯器“解釋”,
如果方法返回 true,則該參數 validOrDefaultName 具有值非空。
但在此段程式碼中,當 validOrDefaultName 為 null 時,該方法返回 true。
除非你在條件中使用了 “!=” 而不是 “==” 運算符
若使用ref修飾符
bool SetDefaultIfNotValid([NotNullWhen(true)] ref string? name)
{
if (name == null)
return true;
name = "defaultName";
return false;
}
編譯器將對上面的程式碼發出警告:
警告訊息如下:
警告 CS8762 參數 'name' 在以 'true' 結束時必須具有非 Null 值。
與前面的例子類似,這裡警告非常合理,因為你用了NotNullWhen屬性向編譯器“解釋”,
如果方法返回 true,則該參數 name 具有值非空。
因為你使用了 '==' 而不是 '!=' 運算符。
若不使用修飾符
bool CheckingForNull([NotNullWhen(true)] string? name)
{
if (name == null)
return true;
Console.WriteLine("name is null");
return false;
}
這裡的情況與之前的案例類似。按照前面例子的邏輯,這裡應該也發出警告訊息:
Parameter 'name' must have a non-null value when exiting with 'true'。
但是,沒有警告。
微軟這樣的邏輯其實很怪。 WHY???
什麼原因造成的? 不好說~
也許這裡就是所謂一些不顯而易見的地方
了解更多:NotNullWhenAttribute Class
下一篇
在 C# 中 Nullable Reference Types 使用屬性NotNullIfNotNull